/**
 @file msg_server.h
 @brief Interfaz del servicio de intercambio de mensajes con las bibliotecas de usuario.
 @date   06/11/2012
 @version v.0.9
 @author Julian Ovalle
 julianovalle@ula.ve
 */

#ifndef MSG_SERVER_H_
#define MSG_SERVER_H_

#include <sys/socket.h>

#include "message_def.h"
#include "app.h"
#include "message.h"
#include "list.h"

#define MSG_SERVER_DEBUG

//! @brief Estructura que almacena la lista de nodos que será visualizada por la interfaz cliente.
typedef struct {
    char id[20]; //!< Identificador de nodo. Máximo 20 caracteres y distinto de BROADCAST_ID @see BROADCAST_ID
    struct list_head list; //!< Representa los apuntadores de la lista de nodos
} node_t;

/*!
 @brief Inicializa el servicio de intercambio de mensajes abriendo el socket de atención e
 inicializando las capas inferiores. Crea una lista de nodos basada en identificadores que la interfaz cliente utiliza. @see node_t
 @return 0 en caso de exito. -1 en caso de error.
 */
int msgServerInit();

/*!
 @brief Servidor de intercambio de mensajes, recibe solicitudes de la interfaz cliente, envía
 los comandos y entrega las respuestas haciendo uso total de la funcionalidad de las capas inferiores.
 @return 0 en caso de exito. -1 en caso de error.
 */
int msgServer();

/*!
 @brief Finaliza el servicio de intercambio de mensajes cerrando el socket de atención y finalizando las capas inferiores.
 @return 0 en caso de exito. -1 en caso de error.
 */
int msgServerExit();

/*!
 @brief Verifica si la lista de nodos está vacía
 @return 1 si la lista está vacía, 0 en caso contrario
 */
int nodeListEmpty();

/*!
 @brief Envía la lista de nodos a la interfaz cliente
 @return 0 en caso de exito. -1 en caso de error.
 */
int sendNodeList(int s);

/*!
 @brief Actualiza la lista de nodos mediante un nuevo descubrimiento de nodos. @see nodeDiscovery()
 @return 0 en caso de exito. -1 en caso de error.
 */
int nodeListUpdate();

/*!
 @brief Obtiene si existe y bajo solicitud del usuario, la respuesta al último comando enviado en unicast y la entrega a la interfaz cliente.
 @param s Descriptor del socket hacia el cliente.
 @param command Identificador del comando que originó la respuesta
 @param id Identificador del nodo que envió la respuesta
 @return 0 en caso de exito. -1 en caso de error.
 */
int deliverResponse(int s, uint8_t command, char *id);

/*!
 @brief Espera por conexiones desde alguna bilioteca cliente y provee un socket conectado a dicho cliente.
 @param fd Socket activo por el que se escuchará por conexiones. @see openSocket
 @return Descriptor al socket conectado al cliente. -1 en caso de error.
 */
int acceptClient (int fd);

int attendClient (int fd);

#endif /* MSG_SERVER_H_ */
